package com.cj.sys.service.security;

import java.util.HashMap;
import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cj.common.orm.hibernate.EntityManager;
import com.cj.common.orm.hibernate.HibernateDao;
import com.cj.sys.dao.security.SysConfigDao;
import com.cj.sys.entity.security.SysConfig;
import com.cj.sys.service.ServiceException;

/**
 * <p> </p>
 * @author cj(axxxx2000@126.com)  2009-12-16
 */ 
@Service
@Transactional
public class SysConfigManager extends EntityManager<SysConfig, Long> implements BeanPostProcessor {
	public static final int MAP_SIZE = 10;
	private static HashMap<String,String> configMap;
	private static HashMap<String,HashMap<String,String>> configTypeMap = new HashMap<String,HashMap<String,String>>();
	private static final String NULL_TYPE_RESULT = "该类型变量不存在！";
	private static final String SUCCESS_TYPE_RESULT = " 同步成功！";
	private boolean isInit = false;
	@Autowired
	SysConfigDao sysConfigDao;

	public static String getSystemValue(String key){
		return configMap.get(key);
	}
	/**
	 * <p>返回某一类型的key-value  hashMap】</p>
	 *
	 * @param type
	 * @return
	 */
	public static HashMap<String,String> configByType(String type){
		return configTypeMap.get(type);
	}
	/**
	 * <p>【按类型从数据库中同步】</p>
	 *	--不用synchronized原因--同步权限高--并发不会太大
	 * @param type
	 */
	@Transactional(readOnly = true)
	public String sysConfigByType(String type){
		try {
			List<SysConfig> sysConfigs = sysConfigDao.findBy("type",type);
			if(sysConfigs == null || sysConfigs.size() == 0)
				return NULL_TYPE_RESULT;
//			HashMap<String,String> hashMap = configTypeMap.get(type);
//			hashMap.clear();
			HashMap<String,String> hashMap = new HashMap<String,String>(MAP_SIZE);
			for(SysConfig sysConfig:sysConfigs){
				hashMap.put(sysConfig.getKeyName(), sysConfig.getValue());
			}
			configTypeMap.put(type, hashMap);
			return type + SUCCESS_TYPE_RESULT;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new ServiceException("sysConfigByType Error!"
					+ e.getMessage(), e);
		}
	}
	/**
	 * <p>【同步系统变量】</p>
	 *
	 */
	@Transactional(readOnly = true)
	public void synSystemConfig(){
		try {
			List<SysConfig> systemConfigs = sysConfigDao.findBy("type", SysConfig.SYSTEM_PROPERTY);
			configMap = new HashMap<String,String>(MAP_SIZE);
			for(SysConfig sysConfig:systemConfigs){
				configMap.put(sysConfig.getKeyName(), sysConfig.getValue());
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new ServiceException("synSystemConfig Error!"
					+ e.getMessage(), e);
		}
	}
	
	@Transactional(readOnly = true)
	public String getValue(String key){
		SysConfig sysconfig = sysConfigDao.findByUnique("key", key);
		if(sysconfig == null)
			return null;
		return sysconfig.getValue();
	}
	
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		if(!isInit){
			init();
		}
		return bean;
	}
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		return bean;
	}
	//	@PostConstruct
	private void init(){
		String hql = "select distinct a.type  from SysConfig a ";
		List types = sysConfigDao.find(hql);
		if(types != null){
			for(Object obj : types){
				sysConfigByType(obj.toString());
			}
		}
		isInit = true;
	}
//	public static SysConfigManager getInstance(){
//		WebApplicationContext wac = WebApplicationContextUtils
//		.getRequiredWebApplicationContext(ServletActionContext.getServletContext());
//		return (SysConfigManager)wac.getBean("sysConfigManager");
//	}
	
	@Override
	protected void afterChange(SysConfig sysConfig) {
		if(SysConfig.SYSTEM_PROPERTY.equalsIgnoreCase(sysConfig.getType())){
			if(configMap == null)
				synSystemConfig();
			configMap.put(sysConfig.getKeyName(), sysConfig.getValue());
			return;
		}else{
			HashMap<String,String> hashMap = configTypeMap.get(sysConfig.getType());
			if(hashMap == null){
				String result = sysConfigByType(sysConfig.getType());
				if(NULL_TYPE_RESULT.equalsIgnoreCase(result))
					hashMap = new HashMap<String,String>(MAP_SIZE);
			}
			hashMap.put(sysConfig.getKeyName(), sysConfig.getValue());
			configTypeMap.put(sysConfig.getType(), hashMap);
		}
	}
	
	@Override
	protected HibernateDao<SysConfig, Long> getEntityDao() {
		return sysConfigDao;
	}
}
